//////////////////////////////////////////////
// MaybeSingletonClass.h
//
// Template based on Singleton
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Class ------------------------------------

namespace nkCommon
{
	///
	/// Basic class for Singleton creation.
	/// This variant of it allows to have isolated instances too.
	/// Use by inheriting from the class.
	///
	template <class T> class MaybeSingletonClass
	{
		protected :

			// Current living instance
			inline static T* _instance = nullptr ;

			// Constructor
			MaybeSingletonClass () = default ;

		public :

			// Destructor
			virtual ~MaybeSingletonClass ()
			{
				// Our instance only can be deleted if it's us
				if (this == _instance)
					_instance = nullptr ;
			}

			///
			/// \returns Current living instance.
			/// 
			/// \remark If instance is non existing, it will be created on the spot.
			/// 
			static T* getInstance ()
			{
				if (!_instance)
					_instance = new T (true) ;

				return _instance ;
			}

			///
			/// \returns Current living instance.
			/// 
			/// \remark If instance is non existing, it will be created on the spot.
			/// 
			static T& getInstanceRef ()
			{
				return *getInstance() ;
			}

			///
			/// \returns Current living instance, if any. nullptr otherwise.
			///
			static T* getInstanceIfExisting ()
			{
				return _instance ;
			}

			///
			/// Deletes living instance.
			/// 
			static void kill ()
			{					
				delete _instance ;
				_instance = nullptr ;
			}

		public :

			///
			/// \returns Whether the calling instance is the one accessible as the Singleton (true) or not (false).
			///
			bool isTheSingletonInstance () const
			{
				return _instance == this ;
			}
	} ;
}